package Redis

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"os"
	"queue/library/Log"
	"queue/library/common"
	"sync"
	"time"
)

// docker 容器创建
// docker run -itd --name flw_go --net flw_net --ip 172.14.0.9 -p 7075:80 -v /usr/wwwroot/flwtest/flw_docker/go_queue/:/data/go_queue/ -e GOPATH=/data/go_queue/ golang:latest
// export GOPATH=/data/go_queue
//var RedisHost="114.116.42.22:6379" // baseeco
//var Psssword="baseeco123456"
var RedisHost = "39.100.194.133:6379" //jwp
var Psssword = "jwp123456"

func BenchMain() {
	/**
		本地直连redis:
		优：总请求数200，平均26-28/s，平均耗时耗时 42-37 ms
		劣：总请求数200，平均22-24/s，平均耗时耗时 46-43 ms

		线上直连redis:
		2核机器 ,
		每秒总共处理请求数约 ：连接数*每个连接平均数
		=============================
		连接数：1
		cpu: root: 5-7%  redis: 1.7-2.3%
		总请求数10000，
		优：请求次数8-9，每个连接平均1070-1110/s，平均耗时耗时0.93-0.90 ms
		劣：请求次数8-9，每个连接平均1038-1060/s，平均耗时耗时 0.96-0.94 ms
		------连接池------------------
		------日志------------------
		cpu: root: 11%  redis: 2-4%
		优：请求次数10，每个连接平均1037-1045/s，平均耗时耗时 0.96- 0.95 ms
		=============================
		连接数：10
		cpu: root: 40-42%  redis: 14.3-15.3%
		总请求数10000*10，
		优：请求次数8-9，每个连接平均1050-1080/s，平均耗时耗时0.93-0.92 ms  每秒请求数： 10500-10800
		劣：请求次数8-9，每个连接平均1000-1044/s，平均耗时耗时 0.99-0.95 ms 每秒请求数： 10000-10440
		------连接池------------------
		------日志------------------
		cpu: root: 71-73%  redis: 15%
		优：请求次数12，每个连接平均1030-1065/s，平均耗时耗时 0.96-0.93 ms  每秒请求数： 10300-10650
		劣：请求次数12，每个连接平均1000-1030/s，平均耗时耗时 1-0.96 ms  每秒请求数： 10000-10300
	    （awk:10200-10360 / 10-11s）
		=============================
		连接数：20
		cpu: root: 73-75%  redis: 28.6-29.2%
		总请求数10000*20，
		优：请求次数8-9，每个连接平均1020-1045/s，平均耗时耗时0.98-0.957 ms 每秒请求数：20400-20900
		劣：请求次数8-10，每个连接平均970-1020/s，平均耗时耗时 1.035-0.98 ms
		------日志------------------
		cpu: root: 102-103%  redis: 26%
		优：请求次数10，每个连接平均961=0-980/s，平均耗时耗时 1.04-1.02 ms  每秒请求数： 19200-19600
		劣：请求次数10-11，每个连接平均940-960/s，平均耗时耗时 1.06-1.04 ms  每秒请求数： 18800-19200
		（awk:19200-19600 / 11-12s）
		=============================
		连接数：30
		cpu: root: 91-92.7%  redis: 37.9-38.5%
		总请求数10000*30
		优：请求次数9-10，每个连接平均980-1010/s，平均耗时耗时 1.02-0.99 ms 每秒请求数：29400-30300
		劣：请求次数8-9，每个连接平均950-975/s， 平均耗时耗时  1.05-1.02 ms 每秒请求数：28500-29250
		------连接池------------------
		cpu: root: 92.4-94%  redis: 38.5-39.2%
		优：请求次数9-10，每个连接平均970-1000/s，平均耗时耗时 1.03-0.99 ms 每秒请求数：27000-30000
		劣：请求次数8-9，每个连接平均950-975/s， 平均耗时耗时  1.05-1.02 ms 每秒请求数：28500-29250
		------日志------------------
		cpu: root: 107-108%  redis: 31%
		优：请求次数11-12，每个连接平均850-880/s，平均耗时耗时 1.17-1.13 ms  每秒请求数： 25500-26400
	    劣：请求次数11-12，每个连接平均820-850/s， 平均耗时耗时 1.21-1.17 ms 每秒请求数： 24600-25500
		（awk:25168-25800 / 13s）
		=============================
		连接数：40
		cpu: root: 97-98.7%  redis: 47.9-48.5%
		总请求数10000*40
		优：请求次数8-9，每个连接平均911-934/s，平均耗时耗时1.09-1.07 ms   每秒请求数：36440-37360
		劣：请求次数9-10，每个连接平均886-911/s，平均耗时耗时 1.14-1.09 ms  每秒请求数： 35440-36440
		------连接池------------------
		cpu: root: 99-100%  redis: 45-45.8%
		优：请求次数8-9，每个连接平均900-934/s，平均耗时耗时1.1-1.07 ms   每秒请求数：36000-37360
		劣：请求次数9-10，每个连接平均870-890/s，平均耗时耗时 1.48-1.12 ms  每秒请求数： 34800-35600
		------日志------------------
		cpu: root: 113-115%  redis: 31-32%
		优：请求次数14，每个连接平均700-730/s，平均耗时耗时 1.43- 1.37 ms  每秒请求数： 28000-29200
		劣：请求次数14，每个连接平均680-700/s，平均耗时耗时 1.46- 1.43 ms  每秒请求数： 27200-28000
		（awk:28300-28600 / 15s）
		=============================
		连接数：50
		cpu: root: 102.7-103.7%  redis: 52.7-53%
		总请求数10000*50
		优：请求次数12-13，每个连接平均790-820/s，平均耗时耗时1.26-1.21 ms   每秒请求数：39500-41000
		劣：请求次数12-13，每个连接平均770-790/s，平均耗时耗时 1.29-1.26 ms  每秒请求数： 38500-39500
		------连接池------------------
		cpu: root: 104-104.8%  redis: 48.8-51%
		优：请求次数12-13，每个连接平均800-830/s，平均耗时耗时1.25-1.2 ms   每秒请求数：40000-41500
		劣：请求次数12-13，每个连接平均750-790/s，平均耗时耗时 1.55-1.26 ms 每秒请求数：37500-39500
		------日志------------------
		cpu: root: 119-120%  redis: 31-32%
		优：请求次数17，每个连接平均590-611/s，平均耗时耗时 1.69- 1.63 ms  每秒请求数： 29500-30550
		劣：请求次数17，每个连接平均572-590/s，平均耗时耗时 1.75- 1.69 ms  每秒请求数： 28500-29500
		（awk:29800-30100 / 18s）
		=============================
		连接数：60 【基本到顶了】
		cpu: root: 104-104.7%  redis: 56-56.7%
		总请求数10000*60
		优：请求次数13-14，每个连接平均700-740/s，平均耗时耗时1.26-1.35 ms   每秒请求数：42000-44400
		劣：请求次数13-14，每个连接平均690-700/s，平均耗时耗时 1.44-1.42 ms  每秒请求数： 41400-42000
		------连接池------------------
		cpu: root: 106-106.3%  redis: 51-52.2%
		优：请求次数12-13，每个连接平均700-730/s，平均耗时耗时1.42-1.36 ms   每秒请求数：42000-43800
		劣：请求次数12-13，每个连接平均670-700/s，平均耗时耗时 1.49-1.42 ms  每秒请求数：40200-42000
		------日志------------------
		cpu: root: 122-124%  redis: 29-31%
		优：请求次数19，每个连接平均500-526/s，平均耗时耗时 2.08- 1.90 ms  每秒请求数： 30000-31560
		劣：请求次数19，每个连接平均480-590/s，平均耗时耗时 1.75- 1.69 ms  每秒请求数： 28800-30000
		（awk:30700-31100 / 20-21s）
		=============================
		连接数：70 【降了】
		cpu: root: 106-107%  redis: 53-53.7%
		总请求数10000*70
		优：请求次数14-15，每个连接平均500-520/s，平均耗时耗时1.67-1.58 ms   每秒请求数：438000-45990
		劣：请求次数14-15，每个连接平均480-500/s，平均耗时耗时1.89-1.81-1.67 ms  每秒请求数：37100-40150-438000
		====连接池================================================================================
		cpu: root: 120-130%  redis: 33-34%
		优：请求次数19，每个连接平均440-450-470/s，平均耗时耗时2.22-2.23-2.13 ms   每秒请求数：30800-31500-32900
		------日志------------------
		cpu: root: 129-130%  redis: 29-31%
		优：请求次数22，每个连接平均430-460/s，平均耗时耗时 2.32- 2.16 ms  每秒请求数： 30100-32200
		（awk:31800-32200 / 23s）
		=============================
		连接数：80
		cpu: root: 129-130%  redis: 30-31.6%
		（awk:32700-33100 / 26s）
		=============================
		连接数：90
		cpu: root: 130-130.6%  redis: 31-32%
		（awk:33100-33500 / 28s）
		=============================
		连接数：90
		cpu: root: 127-128%  redis: 33-34%
		（awk:33100-33600 / 31s）
	*/
	//清空日志文件方便统计
	date := time.Now().Format(Logger.FileNameFormat)
	fileName := date + Logger.Suffix
	FilePath := "/data/go_queue/src/queue/runtime/redis/" + fileName
	file, err := os.OpenFile(FilePath, os.O_CREATE| /*os.O_WRONLY|os.O_APPEND|*/ os.O_TRUNC, 0666) //追加
	fmt.Println(file, err)
	file.Close()
	//bench(60, 10000)
	benchPool(DefaultCreateNum, 10000)
}

func bench(connNum, requestNum int) {
	//connNum:=1 //连接数 ; requestNum:=10 //总请求数
	Logger.LogDepth = 2 // 重写日志调用文件的位置
	wa := sync.WaitGroup{}
	fmt.Println("序号\t请求\t请求\t共请求\t共耗时\t平均耗时(毫秒)")
	for c := 0; c < connNum; c++ {
		wa.Add(1)
		go func(c int) {
			redisConn1, _ := redis.Dial("tcp", RedisHost, redis.DialKeepAlive(0))
			redisConn1.Send("auth", Psssword)
			//redisConn := NewRedisConnect(RedisHost, "jwp123456", "tcp",0)
			timer1 := common.NewTimer()
			startReq := 0
			index := 0
			for req := 0; req < requestNum; req++ {
				redisConn1.Do("get", "name")
				//redisConn1.Do("set", "name", "lawao")
				//redisConn.Get("name")
				spend := timer1.SpendMillisecond()
				cont := req - startReq
				if spend >= 1000 {
					timer1.StartTime = time.Now()
					fmt.Printf("%s\t%d\t%d\t%d\t%d\t%f \n", fmt.Sprintf("%d-%d", c, index), startReq, req, cont, spend, float32(spend)/float32(cont))
					startReq = req
					index++
				}
			}
			spend := timer1.SpendMillisecond()
			cont := requestNum - startReq
			fmt.Printf("%s\t%d\t%d\t%d\t%d\t%f \n", fmt.Sprintf("%d-%d", c, index), startReq, requestNum, cont, spend, float32(spend)/float32(cont))
			wa.Done()
		}(c)
	}
	wa.Wait()
	if wr, ok := Logger.Writer.(*Log.Writer); ok {
		wr.Wait()
	}
}

func benchPool(connNum, requestNum int) {
	//connNum:=1 //连接数 ; requestNum:=10 //总请求数
	Logger.LogDepth = 2 // 重写日志调用文件的位置
	wa := sync.WaitGroup{}
	fmt.Println("序号\t请求\t请求\t共请求\t共耗时\t平均耗时(毫秒)")
	for c := 0; c < connNum; c++ {
		wa.Add(1)
		go func(c int) {
			redisConn := Pool.GetRedisConn(fmt.Sprintf("%d", c))
			timer1 := common.NewTimer()
			startReq := 0
			index := 0
			for req := 0; req < requestNum; req++ {
				redisConn.LogId = fmt.Sprintf("%d-%d", c, req)
				redisConn.Get("name")
				spend := timer1.SpendMillisecond()
				cont := req - startReq
				if spend >= 1000 {
					timer1.StartTime = time.Now()
					fmt.Printf("%s\t%d\t%d\t%d\t%d\t%f \n", fmt.Sprintf("%d-%d", c, index), startReq, req, cont, spend, float32(spend)/float32(cont))
					startReq = req
					index++
				}
			}
			spend := timer1.SpendMillisecond()
			cont := requestNum - startReq
			Pool.AddRedisCoon(redisConn)
			fmt.Printf("%s\t%d\t%d\t%d\t%d\t%f \n", fmt.Sprintf("%d-%d", c, index), startReq, requestNum, cont, spend, float32(spend)/float32(cont))
			wa.Done()
		}(c)
	}
	wa.Wait()
	if wr, ok := Logger.Writer.(*Log.Writer); ok {
		wr.Wait()
	}
}
